package com.yjz.common.util

import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import java.util.concurrent.ConcurrentHashMap

/**
 *作用 : 基于livedata的事件总线
 *作者 : yjz
 *时间 : 2025/3/21 10:42
 *事件发送：
 *  LiveDataBus.with<String>("stickyData").setStickyData("event data")
 * 事件接受
 *  LiveDataBus.with<String>("stickyData").observerSticky(this, false) { value ->
 *             showToast("receiver event data:$value")
 *         }
 *
 *
 */
object LiveDataBus {

    private val eventMap = ConcurrentHashMap<String, StickLiveData<*>>()

    fun <T> with(eventTag: String): StickLiveData<T> {
        var stickLiveData = eventMap[eventTag]
        if (stickLiveData == null) {
            stickLiveData = StickLiveData<T>(eventTag)
            eventMap[eventTag] = stickLiveData
        }
        return stickLiveData as StickLiveData<T>
    }

    class StickLiveData<T>(var eventTag: String) : LiveData<T>() {
        var mStickLiveData: T? = null
        var mVersion = 0

        fun setStickyData(stickLiveData: T) {
            this.mStickLiveData = stickLiveData
            setValue(stickLiveData)
        }

        fun postStickyData(stickLiveData: T) {
            this.mStickLiveData = stickLiveData
            postValue(stickLiveData)
        }

        override fun setValue(value: T) {
            mVersion++
            super.setValue(value)
        }

        override fun postValue(value: T) {
            mVersion++
            super.postValue(value)
        }

        override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
            this.observerSticky(owner, false, observer)
        }

        fun observerSticky(owner: LifecycleOwner, sticky: Boolean, observer: Observer<in T>) {
            owner.lifecycle.addObserver(object : LifecycleEventObserver {
                override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
                    // 发送销毁事件，移除livedata
                    if (event == Lifecycle.Event.ON_DESTROY) {
                        eventMap.remove(eventTag)
                    }
                }
            })
            super.observe(owner, StickyObserver(this, sticky, observer))
        }
    }
}

/**
 * sticky 不等于true , 只能接收到注册之后发送的消息，如果要接收黏性事件，则sticky需要传递为true
 */
class StickyObserver<T>(private var stickLiveData: LiveDataBus.StickLiveData<T>, private var sticky: Boolean, private var observer: Observer<in T>) :
    Observer<T> {
    // lastVersion和stickLiveData的version相等，是为了控制粘性事件的分发。
    private var lastVersion = stickLiveData.mVersion

    override fun onChanged(value: T) {
        if (lastVersion >= stickLiveData.mVersion) {
            // 就说明stickyLiveData  没有更新的数据需要发送
            if (sticky && stickLiveData.mStickLiveData != null) {
                //分发黏性事件
                observer.onChanged(stickLiveData.mStickLiveData!!)
            }
            return
        }
        lastVersion = stickLiveData.mVersion
        observer.onChanged(value)
    }
}
